﻿using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;
using xraiding.Models;

namespace xraiding.ViewModels
{
    public class UserPreferencesViewModel
    {
        private readonly XRaidingEntities _entities;

        [Display(Name="Battle.Net Tag (this is how people will invite you to a raid)")]
        public string BattleNetTag { get; set; }

        [Display(Name="Looking for more")]
        public bool LookingForMore { get; set; }

        [Display(Name="Looking for group")]
        public bool LookingForGroup { get; set; }

        [Display(Name="Time Zone")]
        public int SelectedTimeZone { get; set; }

        [Display(Name = "Describe how you want to play. Casual, hardcore?")]
        [MaxLength(250)]
        public string GameplayStyleDescription { get; set; }

        [Display(Name = "Describe your raid experience")]
        [MaxLength(250)]
        public string RaidExperience { get; set; }

        [Display(Name = "Which raids are you interested in?")]
        [MaxLength(250)]
        public string RaidInterest { get; set; }

        [Display(Name = "Access to voice enabled chat?")]
        public bool AccessToVoiceEnabledChat { get; set; }

        private List<TimeZoneInfo> _timeZones;
        public List<TimeZoneInfo> TimeZones
        {
            get
            {
                if (_timeZones == null)
                    SetTimeZones();
                return _timeZones;
            }
            set { _timeZones = value; }
        }

        public List<AvailableTimeSlotViewModel> TimeAvailability { get; set; }
        public List<DayInfo> Days { get; set; }        
        public List<HourInfo> Hours { get; set; }
        public UserPreferencesViewModel()
        {
            _entities = XRaidingRepository.GetXRaidingConnection(); 
            SetTimeZones();
            Days = new List<DayInfo>();
            _entities.Days.ToList().ForEach(d => Days.Add(new DayInfo { DayId = d.DayId, Name = d.Name }));
            Hours = new List<HourInfo>();
            _entities.Hours.ToList().ForEach(h => Hours.Add(new HourInfo { HourId = h.HourId, Name = h.Name }));
            TimeAvailability = new List<AvailableTimeSlotViewModel>();
            Initialize();
        }        

        private void Initialize()
        {
            var userId = XRaidingRepository.GetUserId();
            var userPreference = (from u in _entities.UserPreferences
                                  where u.UserId == userId
                                  select u).SingleOrDefault();
            if(userPreference != null)
            {
                BattleNetTag = userPreference.BattleNetTag;
                LookingForGroup = userPreference.LookingForGroup.HasValue && userPreference.LookingForGroup.Value;
                LookingForMore = userPreference.LookingForMore.HasValue && userPreference.LookingForMore.Value;
                SelectedTimeZone = userPreference.TimeZone.TimeZoneId;
                GameplayStyleDescription = userPreference.GameplayStyleDescription;
                AccessToVoiceEnabledChat = userPreference.AccessToVoiceEnabledChat.HasValue && userPreference.AccessToVoiceEnabledChat.Value;
                RaidExperience = userPreference.RaidExperience;
                RaidInterest = userPreference.RaidInterest;

                var timeAvailability = (from u in _entities.UserTimeAvailabilities
                                        where u.UserId == userId
                                        select u).ToList();
                for(int index = 0; index < timeAvailability.Count; index++)
                {
                    var availableTime = timeAvailability[index];
                    TimeAvailability.Add(new AvailableTimeSlotViewModel()
                                             {
                                                 SelectedDay = availableTime.DayId,
                                                 SelectedStartTime = availableTime.StartHourId.HasValue ? availableTime.StartHourId.Value : 0,
                                                 SelectedEndTime = availableTime.EndHourId.HasValue ? availableTime.EndHourId.Value : 0
                                             });
                }
            }
        }

        public void Save()
        {
            var userId = XRaidingRepository.GetUserId();
            var userPreference = (from u in _entities.UserPreferences
                                  where u.UserId == userId             
                                  select u).SingleOrDefault();
            if(userPreference == null)
            {
                userPreference = new UserPreference();
                userPreference.UserId = userId;
                _entities.UserPreferences.AddObject(userPreference);                
            }            
            userPreference.BattleNetTag = BattleNetTag;
            userPreference.LookingForGroup = LookingForGroup;
            userPreference.LookingForMore = LookingForMore;
            userPreference.TimeZoneId = SelectedTimeZone;
            userPreference.GameplayStyleDescription = GameplayStyleDescription;
            userPreference.AccessToVoiceEnabledChat = AccessToVoiceEnabledChat;
            userPreference.RaidExperience = RaidExperience;
            userPreference.RaidInterest = RaidInterest;
            _entities.DeleteTimeAvailabilityForUser(userId);
            TimeAvailability.ForEach((f)=> _entities.UserTimeAvailabilities.AddObject(new UserTimeAvailability()
                                                                                          {
                                                                                              UserId = userId,
                                                                                              DayId = f.SelectedDay,
                                                                                              StartHourId = f.SelectedStartTime,
                                                                                              EndHourId = f.SelectedEndTime
                                                                                          }));
            _entities.SaveChanges();
        }

        private void SetTimeZones()
        {
            TimeZones = new List<TimeZoneInfo>();
            _entities.TimeZones.ToList().ForEach(t => TimeZones.Add(new TimeZoneInfo { TimeZoneId = t.TimeZoneId, Description = t.Description }));
        }      
    }   

    public class TimeZoneInfo
    {
        public int TimeZoneId { get; set; }
        public string Description { get; set; }
    }     
    
    public class DayInfo
    {
        public int DayId { get; set; }
        public string Name { get; set; }
    }

    public class HourInfo
    {
        public int HourId { get; set; }
        public string Name { get; set; }
    }
}